#include "stdafx.h"
#include "include/Exceptions.h"
#include "../String.h"

namespace Gs
{
	bool IsIdentifierChar(char c);
	bool IsStartOfIdentifier(char c);

	// Initialises a new instance of the string.
	String::String(const char *str)
		: _buffer(0), _size(0), _hash(0)
	{
		if (str)
		{
			unsigned int len = strlen(str);
			_buffer = new char[len + 1];
			strcpy(_buffer, str);
		}
	}
	
	// Initialises a new instance of the string.
	String::String(unsigned int size)
		: _buffer(new char[size]), _size(0)
	{
		if (size)
			_buffer[0] = 0;
	}

	// Destroys the instance.
	String::~String()
	{
		delete [] _buffer;
	}

	// Gets a pointer to the C-string buffer.
	const char *String::GetCString() const
	{
		return _buffer;
	}

	// Gets a pointer to the buffer.
	char *String::GetBuffer()
	{
		return _buffer;
	}

	// Gets the length of the string.
	int String::GetLength() const
	{
		return strlen(_buffer);
	}

	// Gets the hash of the string.
	unsigned int String::GetHash() const
	{
		if (_hash)
			return _hash;
		unsigned int h = 0;
		for(const char *p = _buffer; *p; p++)
			h = 31 * h + (*p);
		return h;
	}
	
	// Determines if the two strings are equal.
	bool String::IsEqual(String *string) const
	{
		return !strcmp(_buffer, string->_buffer);
	}

	// Determines if the string is a valid identifier.
	bool String::IsIdentifier() const
	{
		if (!IsStartOfIdentifier(_buffer[0]))
			return false;
		for(const char *s = _buffer + 1; *s; s++)
			if (!IsIdentifierChar(*s))
				return false;
		return true;
	}
}